-module(client).
-author("ShenDatian").
-behaviour(application).

-include("cus.hrl").

%% API
-export([start/0, stop/0]).

-export([start/2, stop/1]).

-export([get_sup/0, start_redis/5, get_user_token/1]).

-define(SERVER_APPS, [sasl, client]).
-define(PROCNAME, 'client_redis_').

start() ->
  application:start(crypto),
%  application:start(emysql),
  application:start(client).


stop() ->
  init:stop(),
  ok.


%% don't change the starting sequence!
start(_StartType, _StartArgs) ->
  {ok, Pid} = client_sup:start_link(),
  io:format("start sup : ~p~n", [Pid]),

  [Host, Port, User, Pwd, DB, Encode, Size] = application:get_env(client, mysql, []),
  RM = cus_mysql:start(?list(Host), Port, ?list(User), ?list(Pwd), ?list(DB), Encode, Size),
  io:format("start emysql : ~p~n", [RM]),

  [_Host2, Port2, DB2, _Pwd2, Size2] = application:get_env(client, redis, []),
%%   R = start_redis(?list(Host2), Port2, DB2, "", Size2),
%%   R = start_redis("123.59.11.181", Port2, DB2, "", Size2),
  R = start_redis("192.168.120.81", Port2, DB2, "", Size2),
  io:format("start redis : ~p~n", [R]),
  client_manager:start(),

  {ok, Pid}.

%% start(_StartType, _StartArgs) ->
%%   {ok, Pid} = client_sup:start_link(),
%%   io:format("start sup : ~p~n", [Pid]),
%%
%%   R = cus_redis:start("127.0.0.1", 6379, 1, "", 100),
%%   io:format("start redis : ~p~n", [R]),
%%
%%   client_redis:start_link(),
%%
%%   {ok, Pid}.


stop(_State) ->
  application:stop(client),
  init:stop(),
  ok.

get_sup() ->
  whereis(client_sup).



start_redis(Host, Port, DB, Pwd, Size) ->
    lists:foreach(fun(Index) ->
                          case eredis:start_link(Host, Port, DB, Pwd) of
                              {ok, Client} ->
                                  ProcName = get_proc_name(Index),
                                  register(ProcName, Client),
                                  io:format("Redis client : ~p started~n", [ProcName]),
                                  {ok, Client};
                              {error, _} = Err ->
                                  io:format("Failed to start redis client: ~p ~n", [Err]),
                                  Err
                          end
                  end, lists:seq(1, Size)).

get_proc_name(Index) ->
    Name = erlang:atom_to_list(?PROCNAME) ++ erlang:integer_to_list(Index),
    erlang:list_to_atom(Name).


get_redis_proc(Key) ->
  [_Host, _Port, _DB, _Pwd, Size] = application:get_env(client, redis, []),
  Index = erlang:phash(Key, Size),
  get_proc_name(Index).


get_user_token(Uid) ->
  ProcName = get_redis_proc(Uid),
  safe_q(ProcName, ["GET", "idBindToken_" ++ Uid]).



safe_q(ProcName, Cmd) ->
%%   io:format("save q : ~p~n", [whereis(ProcName)]),
  case whereis(ProcName) of
    undefined ->
      [Host, Port, DB, Pwd, _Size] = application:get_env(client, redis, []),
      case eredis:start_link(?list(Host), Port, DB, ?list(Pwd)) of
        {ok, Client} ->
          register(ProcName, Client),
          case eredis:q(ProcName, Cmd) of
            {ok, V} ->
              V;
            Err ->
              io:format("Failed to start redis client: ~p~n", [Err]),
              <<>>
          end;
        {error, Err} ->
          io:format("Failed to start redis client: ~p~n", [Err]),
          <<>>
      end;
    _ ->
      case eredis:q(ProcName, Cmd) of
        {ok, V} ->
          V;
        Err ->
          io:format("Failed to start redis client: ~p~n", [Err]),
          <<>>
      end
  end.
